package com.xxx.blog.service.impl;

import com.github.pagehelper.PageHelper;
import com.xxx.blog.domain.ArticleType;
import com.xxx.blog.mapper.ArticleTypeMapper;
import com.xxx.blog.query.ArticleTypeQuery;
import com.xxx.blog.service.IArticleTypeService;
import com.xxx.vo.ArticleTypeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ArticleTypeServiceImpl implements IArticleTypeService {
    @Autowired
    private ArticleTypeMapper articleTypeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<ArticleType> findAll() {
        return articleTypeMapper.findAll();
    }

    @Override
    public ArticleType findOne(Long id) {
        return articleTypeMapper.findOne(id);
    }

    @Override
    public List<ArticleType> queryPage(ArticleTypeQuery articleTypeQuery) {
        PageHelper.startPage(articleTypeQuery.getCurrentPage(), articleTypeQuery.getPageSize());
        return articleTypeMapper.queryPage(articleTypeQuery);
    }

    @Override
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")
    public void addArticleType(ArticleType articleType) {
        articleTypeMapper.addArticleType(articleType);
    }

    @Override
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")
    public void updateArticleType(ArticleType articleType) {
        articleType.setUpdateTime(new Date());//解决更新时间
        articleTypeMapper.updateArticleType(articleType);
    }

    @Override
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")
    public void deleteArticleType(Long id) {
        articleTypeMapper.deleteArticleType(id);
    }

    @Override
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")
    public void batchArticleType(Long[] ids) {
        articleTypeMapper.batchArticleType(ids);
    }

    @Override
    //会先根据articleType::typeTree从redis获取,如果有就直接用缓存的。如果没有,就执行方法体的代码查询数据库
    @Cacheable(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public List<ArticleType> getTypeTree(Long id) {

       /* List<ArticleType> articleTypes = (List<ArticleType>) redisTemplate.boundValueOps("typeTree").get();//假设法

        if (articleTypes != null) {//如果redis中有就使用redis的
            System.out.println("数据来自redis");
            return articleTypes;
        }

        System.out.println("数据来自mysql");
        articleTypes=this.getArticleTypes(id);//否则查询mysql,然后存一份到redis下次就有了
        redisTemplate.boundValueOps("typeTree").set(articleTypes);*/

        return getArticleTypes(id);

    }

    private List<ArticleType> getArticleTypes(Long id) {
        //类型树集合
        List<ArticleType> typeTree = new ArrayList<>();
        //找出所有的数据
        List<ArticleType> articleTypeList = articleTypeMapper.findAll();
        Map<Long, ArticleType> map = new HashMap<>();//封装进map集合
        //进行遍历,先把所有的数据放进map集合中
        for (ArticleType articleType : articleTypeList) {
            map.put(articleType.getId(), articleType);
        }
        //进行遍历判断是否是父类型还是子类型
        for (ArticleType articleType : articleTypeList) {
            //自己不能选自己当父类型,数据库的行就是row,id拿到类型id,跳过本次循环
            if(id.equals(articleType.getId())){
                continue;
            }
            Long parentId = articleType.getParentId();
            if (parentId == null) {
                typeTree.add(articleType);//所有的父类型
            } else {
                ArticleType parent = map.get(parentId);
                //加强判断,防止父类型为空
                if (parent != null) {
                    //在else里面肯定为子类型,把子类型放入子类型集合中
                    parent.getChildren().add(articleType);
                }
            }
        }
        return typeTree;
    }

    @Override
    public List<ArticleTypeVo> articleTypeStatistics() {
            return articleTypeMapper.articleTypeStatistics();
    }
}
